package disign;

import org.omg.PortableServer.ThreadPolicy;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.*;

/**
 * todo
 *
 * @author zhengshan
 * @Date 2023/1/30 9:58
 */
public class TestDemo3 {

    /**
     corePoolSize（核心线程数）：
     这是线程池中始终保持存活的线程数量。
     通俗地说，即使没有任务要执行，线程池也会一直保持这些核心线程的存在。
     */
    int corePoolSize = 5;

    /**
     * maximumPoolSize（最大线程数）：
     * 这是线程池中允许的最大线程数量。
     * 如果当前任务数量超过核心线程数，线程池会创建新的线程，但不会超过这个最大线程数。
     */
    int maximumPoolSize = 10;

    /**
     * keepAliveTime（线程空闲时间）：
     * 当线程池中的线程数量大于核心线程数时，多余的线程在空闲时间达到这个值后会被终止并从线程池中移除。
     * 这个时间可以理解为线程的“闲置时间”。
     */
    long keepAliveTime = 1;

    /**
     * unit（时间单位）：
     * 指定了keepAliveTime参数的时间单位，通常是秒、毫秒等。
     */
    TimeUnit unit = TimeUnit.MINUTES;

    /**
     * workQueue（任务队列/阻塞队列）：
     * 用于存放待执行的任务的队列。
     * 当提交的任务数量大于核心线程数时，超过核心线程数的任务会被放入这个队列中等待执行。
     */
    BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>(5);

    /**
     * threadFactory（线程工厂）：
     * 用于创建新线程的工厂。
     * 可以自定义线程的名称、优先级等属性。
     */
    ThreadFactory threadFactory = Executors.defaultThreadFactory();

    /**
     * handler（拒绝策略）：
     * 当任务数量超过最大线程数且队列已满时，用于决定如何处理新任务的策略。
     * 常见的策略有抛出异常、丢弃任务、阻塞等。
     */
    RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

    int finalI = 0;

    public void testThreadPoolExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        for(int i = 0; i < 15; i++){
            finalI ++; // synchronized
            threadPoolExecutor.execute(() -> {

                    System.out.println("--------" + finalI);
            });
        }
    }

    public static void main(String[] args) {
        System.out.println(LocalDateTime.now().with(LocalTime.MIN));
//        new TestDemo3().testThreadPoolExecutor();
//        try {
//            Field field = TestDemo3.class.getDeclaredField("corePoolSize");
//            field.setAccessible(true);
//            System.out.println(field.get(new TestDemo3()));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }
}

